package write.oo;
/**
 * 只要是一个类被编译后都有独立的class文件
 * 包括：普通类，内部类(命名：外部类$内部类)，匿名内部类(外部类$1/2/3...)
 */
public class ClassDemo {
    public static void main(String[] args) {
        //创建对象
        Person p1 = new Person();
        p1.say();
        Person p2 = new Person("张三",20);
        p2.say();

        /**
         * 多态：多种形态
         * 向上造型/自动类型转换：----------看的是前面/引用
         * 超类型的引用指向派生类的对象
         * 能点出来什么，看引用的类型
         *
         * 向下转型/强制类型转换：---------看的是对象，即后面
         *          【向下转型的本质：是先向上造型。多态，永远不可能转换为比对象小的类型】
         *          引用所指向的对象，就是该类型
         *          引用所指向的对象，实现了该接口或继承了该类
         *       强转时若不符合如上条件，则发生ClassCastException类型转换异常
         *
         * 常规使用：在强转之前先通过instanceof来判断引用的对象是否是该类型
         * 注意：instanceof返回boolean结果，它为true的条件就是强转成功的条件
         * 何时需要强转：若想访问的属性/行为在超类中没有，则需要强制类型转换
         *
         * 更了解一句话：派生类可以访问：超类的+派生类的，超类不能访问派生类的
         */
        Aoo o1 = new Coo();
        Boo o2 = (Boo)o1;
        o2.say();

        Boo o3 = new Coo();
        o3.say();

        Coo o4 = new Coo();

//        Doo o5 = (Doo)new Coo();
//        Doo o6 = (Doo)o1;
//        Doo o7 = (Doo)o3;
//        Doo o8 = (Doo)o4;


        /**
         * 匿名内部类：
         * 何时用：若想创建一个派生类的对象，并且对象只创建一次，可以设计为匿名内部类，可以大大简化代码
         *
         * 注意：匿名内部类中不能修改外面局部变量的值
         *
         */
        AbstractClass a = new AbstractClass() {
            @Override
            void sayHello() {

            }
        };
    }
}

class Aoo{
    void say(){
        System.out.println("Aoo");
    }

}

class Boo extends Aoo {
    void say(){
        System.out.println("Boo");
    }

}

class Coo extends Boo {
    void say(){
        System.out.println("Coo");
    }
}

class Doo extends Coo {
    void say(){
        System.out.println("Doo");
    }
}
